#include <bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
using namespace std;

const int N = 1e5 + 5;

int d[N],v[N],a[N],p[N],ed[N],l[N],r[N],pre[N];

struct SegT{
	int tree[N << 2],tag[N << 2],fr[N << 2];
	void push_up(int p)
	{
		tree[p] = max(tree[ls],tree[rs]);
		fr[p] = (tree[p] == tree[ls] ? fr[ls] : fr[rs]);
	}
	void build(int p,int l,int r)
	{
		if (l == r)
		{
			tree[p] = tag[p] = 0;
			fr[p] = l;
			return;
		}
		int mid = (l + r) >> 1;
		build(ls,l,mid);
		build (rs,mid + 1,r);
		push_up(p);
	}
	void push_down(int p)
	{
		if (tag[p])
		{
			tree[ls] += tag[p];
			tree[rs] += tag[p];
			tag[ls] += tag[p];
			tag[rs] += tag[p];
		}
	}
	void modify(int p,int l,int r,int nl,int nr,int val)
	{
		if (nl <= l && r <= nr)
		{
			tree[p] += val;
			tag[p] += val;
			return;
		}
		push_down(p);
		int mid = (l + r) >> 1;
		if (nl <= mid) modify(ls,l,mid,nl,nr,val);
		if (nr > mid) modify(rs,mid + 1,r,nl,nr,val);
		push_up(p);
	}
	int qry(int p,int l,int r,int nl,int nr)
	{
		if (nl <= l && r <= nr) return tree[p];
		int mid = (l + r) >> 1,ret = 0;
		push_down(p);
		if (nl <= mid) ret = max(ret,qry(ls,l,mid,nl,nr));
		if (nr > mid) ret = max(ret,qry(rs,mid + 1,r,nl,nr));
		return ret;
	}
}seg;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	int t;
	cin >> t;
	for (;t > 0;t--)
	{
		int n,m,L,maxv;
		cin >> n >> m >> L >> maxv;
		for (int i = 1;i <= n;i++)
		{
			ed[i] = l[i] = r[i] = pre[i] = 0;
			cin >> d[i] >> v[i] >> a[i];
			if (a[i] < 0) ed[i] = d[i] + v[i] * v[i] / (-2 * a[i]);
			if (a[i] == 0 && v[i] > maxv) l[i] = d[i],r[i] = L;
			if (a[i] > 0)
			{
				if (maxv < v[i]) l[i] = d[i],r[i] = L;
				else
				{
					int pos = d[i] + (maxv * maxv - v[i] * v[i]) / (2 * a[i]) + 1;
					if (pos <= L) l[i] = pos,r[i] = L;
				}
			}
			if (a[i] < 0 && v[i] > maxv)
			{
				int pos = d[i] + (v[i] * v[i] - maxv * maxv) / (-2 * a[i]);
				if ((pos - d[i]) * (-2 * a[i]) == (v[i] * v[i] - maxv * maxv)) pos--;
				l[i] = d[i],r[i] = min(min(L,ed[i]),pos);
			}
		}
		for (int i = 1;i <= m;i++)
			cin >> p[i];
		p[0] = 0;p[m + 1] = INT_MAX;
		for (int i = 1;i <= n;i++)
			l[i] = (lower_bound(p,p + m + 2,l[i]) - p),r[i] = (upper_bound(p,p + m + 2,r[i]) - (p + 1));
		int cnt = 0;
		vector < int > vs[100005];
		for (int i = 1;i <= n;i++)
			if ((l[i] || r[i]) && l[i] <= m && l[i] <= r[i]) cnt++,vs[r[i]].push_back(l[i]);
		cout << cnt << " ";
		seg.build(1,1,m);
		for (int i = 1;i <= m;i++)
		{
			pre[i] = (seg.tree[1] ? seg.fr[1] : 0);
			seg.modify(1,1,n,i,i,seg.tree[1]);
			for (auto j : vs[i]) 
				seg.modify(1,1,n,j,i,1);
		}
		int ans = INT_MAX;
		for (int i = 1;i <= m;i++)
			if (seg.qry(1,1,n,i,i) == cnt)
			{
				int t = i,cnt = 1;
				while (t) t = pre[t],cnt++;
				ans = min(ans,cnt);
			}
		cout << m - ans << endl;
	}
	return 0;
}
